<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/12/2
 * Time: 19:06
 */

namespace app\api\service;

use app\api\model\Order as OrderModel;
use app\api\service\Order as OrderService;
use app\lib\enum\OrderStatusEnum;
use app\lib\enum\OrderTypeEnum;
use think\Exception;
use think\Loader;
use think\Log;

Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');

class Pay
{
    private $orderID;
    private $orderNo;

    function __construct($orderID)
    {
        if(!$orderID){
            throw new Exception('订单号不能为空');
        }

        $this->orderID = $orderID;
    }


    /*
     * 订单有效
     * 检查库存
     * 向微信服务器发送请求  调用支付统一下单接口  preOrder
     * 生成签名
     * */

    // 真实的pay  获取pre pay id
    public function pay()
    {
        OrderService::checkOrderValid($this->orderID, OrderTypeEnum::Buy, OrderStatusEnum::UNPAID);

        // 检查库存
        $orderService = new OrderService();
        $orderState = $orderService->checkOrderState($this->orderID);

        if(!$orderState['pass']){
            return $orderState;
        }

        return $this->makeWxPreOder($orderState);

    }

    // 构建preOrder的参数
    private function makeWxPreOder($orderState){
        $openID = Token::getTokenVar('openid');

        $wxPay = new \WxPayUnifiedOrder();
        $wxPay->SetOpenid($openID);
        $wxPay->SetOut_trade_no($this->orderNo);
        $wxPay->SetTotal_fee($orderState['orderPrice'] * 100);
        $wxPay->SetNotify_url(config('secure.pay_back_url'));
        $wxPay->SetBody('Boook11');
        $wxPay->SetTrade_type('JSAPI');

        return $this->getPaySignature($wxPay);
    }

    // 向微信服务器发送pre_order  成功，微信服务器返回prepay Id
    private function getPaySignature($wxPay){
        // 向微信服务器发送pre_order
        $result = \WxPayApi::unifiedOrder($wxPay);
        if($result['return_code']!='SUCCESS'|| $result['result_code']!='SUCCESS'){
            Log::record($result,'error');
            Log::record('获取预支付订单失败','error');
            throw new Exception('生成预订单失败');
        }

        // 更新order表的prepay id
        $this->updatePrepayID($result['prepay_id']);

        // 生成签名
        return $this->sign($result);
    }

    private function updatePrepayID($prepayID){
        OrderModel::where('id','=',$this->orderID)->update(['prepay_id' => $prepayID]);
    }

    /*
     * 生成签名
     * */
    private function sign($wxOrder)
    {
        $jsApiPayData = new \WxPayJsApiPay();
        $jsApiPayData->SetAppid(config('wx.app_id'));
        $jsApiPayData->SetTimeStamp((string)time());
        $rand = md5(time() . mt_rand(0, 1000));
        $jsApiPayData->SetNonceStr($rand);
        $jsApiPayData->SetPackage('prepay_id=' . $wxOrder['prepay_id']);
        $jsApiPayData->SetSignType('md5');
        // 生成签名
        $sign = $jsApiPayData->MakeSign();
        // 转换为数组
        $rawValues = $jsApiPayData->GetValues();
        $rawValues['paySign'] = $sign;
        unset($rawValues['appId']);
        return $rawValues;
    }
}